package com.topscomm.mpm.mq;

import com.alibaba.fastjson.JSONObject;
import com.rabbitmq.client.Channel;
import com.topscomm.basic.BasicEntity;
import com.topscomm.basic.IBasicService;
import com.topscomm.basic.util.Config;
import com.topscomm.cbo.CboSystemConst.CboTableLogOperateTypeEnum;
import com.topscomm.cbo.pojo.*;
import com.topscomm.cbo.service.*;
import com.topscomm.mis.pojo.MisDeptHeaderEntity;
import com.topscomm.mis.pojo.MisMqMessageAcceptLogEntity;
import com.topscomm.mis.service.IMisMqMessageAcceptLogService;
import com.topscomm.pub.util.SpringUtil;
import com.topscomm.pub.util.StringUtil;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

//import com.topscomm.cbo.pojo.CboErrorLogEntity;
//import com.topscomm.cbo.service.ICboErrorLogService;

/**
 * 用于同步基础信息的mq（消费者）
 *
 * @author 王兴华
 */
@Component
public class MpmBasicHandler {
    @Resource(name = "cboDeptService")
    private ICboDeptService deptService;
    @Resource(name = "cboOrgService")
    private ICboOrgService orgService;
    @Resource(name = "cboUserService")
    private ICboUserService userService;
    @Resource(name = "cboRoleService")
    private ICboRoleService roleService;
    @Autowired
    private IMisMqMessageAcceptLogService misMqMessageAcceptLogService;

    /**
     * 处理CboUser,CboDept,MisEmployee表的数据 createby张龙飞 modifiyby王兴华
     */
    @RabbitListener(queues = {"topscomm.mpm.basicData.sync"}, containerFactory = "rabbitListenerContainerFactory")
    @RabbitHandler
    public void process(String hello, Channel channel, Message message) throws Exception {
        if ("false".equals(Config.getInstance().getValue("mq.basicData.sync.receive", "false"))) {
            channel.basicReject(message.getMessageProperties().getDeliveryTag(), false);
            return;
        }
        String json = "";
        try {
            json = new String(message.getBody(), "utf-8");
            handlerData(json);
            // 手动应答，可删除消息
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (Exception e) {
            e.printStackTrace();
            writeError(e, json, message);
            // 拒绝消息
//			channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
            channel.basicReject(message.getMessageProperties().getDeliveryTag(), false);
            // ack返回false，并重新回到队列
            // channel.basicNack(message.getMessageProperties().getDeliveryTag(), false,
            // true);
            // ErrorUtil.writeLog(e);
        }
    }
    public void handlerData(String json) throws Exception {
        String type = "初始的";
        Map<String, Object> transData = JSONObject.parseObject(json, Map.class);
        String table = transData.get("category").toString();
        String action = transData.get("action").toString();
        List<Map> list = (List<Map>) transData.get("data");
        String primaryKey = "code", packageName = "com.topscomm.cbo.pojo.";
        // 不需要更新MisEmployee
        if (table.equals("MisEmployee")){
            return;
        }
        IBasicService service = (IBasicService) SpringUtil.getBean(StringUtil.lowerFirst(table) + "Service");

        int count = 0;
        for (Map map : list) {
            String whereSql="";
            if("CboUserRole".equals(table))
            {
                CboUserEntity userEntity = userService
                        .queryObjectByWhere("code ='" + map.get("usercode").toString() + "'");
                whereSql="userid = "+ userEntity.getId();
                CboRoleEntity roleEntity = roleService.queryObjectByWhere("code ='" + map.get("rolecode").toString() + "'");
                whereSql=whereSql+" and roleid="+roleEntity.getId();
            }
            if (map.containsKey(primaryKey)&& map.get(primaryKey) != null )
                whereSql = primaryKey + "='" + map.get(primaryKey) + "'";

            if(StringUtil.isEmpty(whereSql))
                continue;

            if (CboTableLogOperateTypeEnum.Delete.equals(action)) {
                type = "删除处理前";
                service.deleteByWhere(whereSql);
                type = "删除处理后";
            } else if (CboTableLogOperateTypeEnum.Insert.equals(action)
                    || CboTableLogOperateTypeEnum.Update.equals(action)){
                type= "转换数据前";
                switchData(map, table);
                type= "转换数据后";
                count = service.getCount(whereSql);
                if (count > 0) {
                    type= "更新处理前";
                    service.updateByWhere(map, whereSql);
                    type= "更新处理后";
                } else {
                    Class<BasicEntity> entityClass = (Class<BasicEntity>) Class
                            .forName(packageName + table + "Entity");
                    BasicEntity entity = (BasicEntity) entityClass.newInstance();
                    type= "新增处理前";
                    entity.convertFromMap(map);
                    service.insert(entity);
                    type= "新增处理后";
                }
            }
        }
        //记录接收日志
        MisMqMessageAcceptLogEntity logEntity=new MisMqMessageAcceptLogEntity();
        logEntity.setTablename(table);
        logEntity.setAcceptlog(json);
        logEntity.setDescription(type);
        misMqMessageAcceptLogService.insert(logEntity);
    }

    private void writeError(Exception e, String json, Message message) {
        CboSystemErrorLogEntity logEntity = new CboSystemErrorLogEntity();
        logEntity.setDisplayerror("接收mq失败");
        logEntity.setDescription(json);
        logEntity.setEnabled(1);
        logEntity.setDisplayerror(e.getMessage());
        logEntity.setSource("[mq]" + message.getMessageProperties().getConsumerQueue());
        ICboSystemErrorLogService errorLogService = (ICboSystemErrorLogService) SpringUtil.getBean("cboSystemErrorLogService");
        errorLogService.insert(logEntity);
    }

    /**
     *
     * @author zhanglongfei
     * @date 2019年7月4日
     * @description 处理数据，主要是把code转id
     */
    private void switchData(Map map, String table) {
        map.remove("id");
        map.remove("adminlevel");

        if (table.equals(CboUserEntity.tableName)) {
            if (map.containsKey("orgcode") && map.get("orgcode") != null
                    && !StringUtil.isEmpty(map.get("orgcode").toString())) {
                CboOrgEntity orgEntity = orgService.queryObjectByWhere("code ='" + map.get("orgcode").toString() + "'");
                if (orgEntity != null) {
                    map.put("orgid", orgEntity.getId());
                }
            }
            if (map.containsKey("deptcode") && map.get("deptcode") != null
                    && !StringUtil.isEmpty(map.get("deptcode").toString())) {
                CboDeptEntity deptEntity = deptService
                        .queryObjectByWhere("code ='" + map.get("deptcode").toString() + "'");
                if (deptEntity != null) {
                    map.put("deptid", deptEntity.getId());
                }
            }
            if (map.containsKey("workorgcode") && map.get("workorgcode") != null
                    && !StringUtil.isEmpty(map.get("workorgcode").toString())) {
                CboOrgEntity orgEntity = orgService
                        .queryObjectByWhere("code ='" + map.get("workorgcode").toString() + "'");
                if (orgEntity != null) {
                    map.put("workorgid", orgEntity.getId());
                }
            }
            if (map.containsKey("workdeptcode") && map.get("workdeptcode") != null
                    && !StringUtil.isEmpty(map.get("workdeptcode").toString())) {
                CboDeptEntity deptEntity = deptService
                        .queryObjectByWhere("code ='" + map.get("workdeptcode").toString() + "'");
                if (deptEntity != null) {
                    map.put("workdeptid", deptEntity.getId());
                }
            }
        } else if (table.equals(CboDeptEntity.tableName)) {
            if (map.containsKey("parentcode") && map.get("parentcode") != null
                    && !StringUtil.isEmpty(map.get("parentcode").toString())) {
                CboDeptEntity deptEntity = deptService
                        .queryObjectByWhere("code ='" + map.get("parentcode").toString() + "'");
                if (deptEntity != null) {
                    map.put("parentid", deptEntity.getId());
                }
            }
            if (map.containsKey("orgcode") && map.get("orgcode") != null
                    && !StringUtil.isEmpty(map.get("orgcode").toString())) {
                CboOrgEntity orgEntity = orgService.queryObjectByWhere("code ='" + map.get("orgcode").toString() + "'");
                if (orgEntity != null) {
                    map.put("orgid", orgEntity.getId());
                }
            }
            if (map.containsKey("headercode") && map.get("headercode") != null
                    && !StringUtil.isEmpty(map.get("headercode").toString())) {
                CboUserEntity userEntity = userService
                        .queryObjectByWhere("code ='" + map.get("headercode").toString() + "'");
                if (userEntity != null) {
                    map.put("headerids", userEntity.getId());
                }
            }
        }else if (table.equals(MisDeptHeaderEntity.tableName)) {
            if (map.containsKey("orgcode") && map.get("orgcode") != null
                    && !StringUtil.isEmpty(map.get("orgcode").toString())) {
                CboOrgEntity orgEntity = orgService.queryObjectByWhere("code ='" + map.get("orgcode").toString() + "'");
                if (orgEntity != null) {
                    map.put("orgid", orgEntity.getId());
                }
            }
            if (map.containsKey("deptcode") && map.get("deptcode") != null
                    && !StringUtil.isEmpty(map.get("deptcode").toString())) {
                CboDeptEntity deptEntity = deptService
                        .queryObjectByWhere("code ='" + map.get("deptcode").toString() + "'");
                if (deptEntity != null) {
                    map.put("deptid", deptEntity.getId());
                }
            }
            if (map.containsKey("workorgcode") && map.get("workorgcode") != null
                    && !StringUtil.isEmpty(map.get("workorgcode").toString())) {
                CboOrgEntity orgEntity = orgService
                        .queryObjectByWhere("code ='" + map.get("workorgcode").toString() + "'");
                if (orgEntity != null) {
                    map.put("workorgid", orgEntity.getId());
                }
            }
            if (map.containsKey("workdeptcode") && map.get("workdeptcode") != null
                    && !StringUtil.isEmpty(map.get("workdeptcode").toString())) {
                CboDeptEntity deptEntity = deptService
                        .queryObjectByWhere("code ='" + map.get("workdeptcode").toString() + "'");
                if (deptEntity != null) {
                    map.put("workdeptid", deptEntity.getId());
                }
            }
            if (map.containsKey("fimanagercode") && map.get("fimanagercode") != null
                    && !StringUtil.isEmpty(map.get("fimanagercode").toString())) {
                CboUserEntity userEntity = userService
                        .queryObjectByWhere("code ='" + map.get("fimanagercode").toString() + "'");
                if (userEntity != null) {
                    map.put("fimanagerid", userEntity.getId());
                }
            }
            if (map.containsKey("hrmanagercode") && map.get("hrmanagercode") != null
                    && !StringUtil.isEmpty(map.get("hrmanagercode").toString())) {
                CboUserEntity userEntity = userService
                        .queryObjectByWhere("code ='" + map.get("hrmanagercode").toString() + "'");
                if (userEntity != null) {
                    map.put("hrmanagerid", userEntity.getId());
                }
            }
        }

    }
}

